import { nextTick, watch, reactive } from 'vue'

// 让 dom 可以拖拽
import domDrag from './controller/domDrag'
// 设置排序
import setOrder from './controller/set-order'

import type {
  IFormItem,
  IFormItemList
} from '../types/20-form-item'

import type {
  IFromMeta 
} from '../types/30-form'

import type {
  IDragInfo,
  IDragEvent
} from '../types/70-drag'


/**
 *  数据列表的拖拽相关的操作，记录调整后的td 的宽度，调整td的顺序，移除td
 * @param formMeta 列表的 meta
 * @param itemMeta 表单子控件 集合
 * @param form 表单子控件 集合
 * @param deleteCol 移除 th 的确认对话框
 * @returns 
 */
export default function formDrag(
  formMeta: IFromMeta,
  itemMeta: IFormItemList,
  form: HTMLTableElement,
  deleteCol: (col: any, cb: () => void) => void,
  modCol: (colId: string | number, dragInfo: IDragInfo, event: any) => void
) {
  /**
   * 移除选择的字段
   * @param dragInfo 拖拽信息
   */
  const _setRemove = (dragInfo: IDragInfo) => {
    const col = itemMeta[dragInfo.sourceId]
    // 调用外部的确认对话框
    deleteCol(col, () => {
      // 确认移除，才会执行回调
      formMeta.colOrder.splice(dragInfo.sourceIndex, 1)
      
    })
  }

  /**
   * 设置 控件占的格子数，和表单列数
   */
  const _setThAlgin = (dragInfo: IDragInfo) => {
    if (dragInfo.ctrl) {
      // 修改列数
      if (dragInfo.isLeft) {
        // 判断现在的列数
        if (formMeta.columnsNumber > 1) formMeta.columnsNumber --
      } else {
        if (formMeta.columnsNumber < 8) formMeta.columnsNumber ++

      }
    } else {
      // 修改控件占的格子数
      // 控件ID
      const id = dragInfo.sourceId
      const colMeta = itemMeta[id]
      // 当前的格子数
      if (typeof colMeta.meta.colCount !== 'number') colMeta.meta.colCount = 1
      const colCount = colMeta.meta.colCount

      if (dragInfo.isLeft) {
        // 减少格子数
        if (colCount > -7) colMeta.meta.colCount --
        if (colMeta.meta.colCount === 0) colMeta.meta.colCount = -2
      } else {
        // 增加格子数
        if (colCount < 8) colMeta.meta.colCount ++
        if (colMeta.meta.colCount === -1) colMeta.meta.colCount = 1
      }
    }
    
  }
 
  /**
   * 列表的初始化设置
   */
  const formSetup = () => {
   
    // 拖拽信息
    const dragInfo = reactive<IDragInfo>({
      timeout: null, // 设置拖拽出去的 setTimeout
      oldDom: {style:{border:''}}, // 记录之前的拖拽 dom
      state: '', // 拖拽状态，拖拽中（pending），拖拽结束（end）
      offsetX: 0,
      isLeft: true, // 是否在 th 的左侧结束拖拽，左侧或者右侧。
      ctrl: false, // 是否按下了ctrl
      sourceId: '', // 开始拖拽的th对应的字段ID
      targetId: '', // 结束拖拽的th对应的字段ID
      sourceIndex: 0, // 开始拖拽的位置
      targetIndex: 0 // 结束拖拽的位置
    })

    const formItem = Array.from(form.children)
    
    // 整合拖拽事件
    const _dragEvent = {
      setAlign() {
        _setThAlgin(dragInfo)
      },
      setOrder() {
        setOrder(formMeta.colOrder, dragInfo) // 调整顺序、交换位置
      },
      removeDom() {
        _setRemove(dragInfo) // 移除
      },
      modCol(colId, event) {
        if (typeof modCol === 'function')
          modCol(colId, dragInfo, event) // 单击控件（字段）触发的事件
      }
    }
    
    // 遍历表单子控件
    formItem.forEach((element, i: number) => {
      const label = element.children[0].children[0]
      const ctrl = element.children[0].children[1]
      const colId = formMeta.colOrder[i]
      // 给 th 设置拖拽事件
      const thDrag = new domDrag(label, formMeta.colOrder, dragInfo, colId, _dragEvent)
    })
    document.ondrop = (event) => {
    }
  }

  
  // 监听 字段变化，重新设置拖拽。
  watch(formMeta, () => {
    nextTick(() => {
      setTimeout(() => {
        formSetup() // 重新绘制
      }, 500)
    })
  })

  return {
    formSetup // 列表设置拖拽
  }

}